#include "log.h"
#include <signal.h>
// 日志系统配置
LogSystemConfig glob_log_system_config = {
    .level = GLOB_LOG_EVEL,
    .enable_color = ENABLE_COLOR,
    .enable_file_logging = ENABLE_FILE,
    .log_file_path = NULL,
};


static void delete_file(char *filename)
{
    if(filename == NULL)
    {
        return;
    }
    if(access(filename,F_OK) == 0)
    {
        remove(filename);
    }
}

static int is_leap_year(int years)
{
    int ret = 0;
    if( years%4 == 0)
    {
        if(years%100 != 0)
        {
            ret = 1;
        }
    }
    if(years%400 == 0)
    {
        ret = 1;
    }
    return ret;
}
static void signal_handler(int signum)
{
    if(signum == SIGALRM)
    {
        time_t ntime;
        struct tm *ltm;
        int mday;
        ntime = time(NULL);
        ltm = localtime(&ntime);
        snprintf(glob_log_system_config.log_file_path ,MAX_FILE_NAME_LEN,"%s_%d.log",FILE_NAME,ltm->tm_mday);
        printf("logfile_name = %s \n",glob_log_system_config.log_file_path);
        //delete file
        delete_file(glob_log_system_config.log_file_path);
        switch(ltm->tm_mon)
        {
            case 2 :    if(ltm->tm_mday == 1) 
                        {
                            if(is_leap_year(ltm->tm_yday+1900) == 0) 
                            {
                                delete_file("log_mday_29.log"); 
                            }
                            delete_file("log_mday_30.log");
                            delete_file("log_mday_31.log");  
                        } break;
            case 4 :
            case 6 :
            case 9 :
            case 11 :  if(ltm->tm_mday == 1) {delete_file("log_mday_31.log");}  break;
        }
        //LOG_DEBUG(logger,"signal alarm!");
    }
}


int init_log_file_rule()
{
    struct itimerval its;
    time_t etime,stime;
    struct tm *ltm;
    int i;
    for(i=0;i<3;i++)
    {
        glob_log_system_config.log_file_path = calloc(MAX_FILE_NAME_LEN,sizeof(char));
        if(glob_log_system_config.log_file_path)
        {
            break;
        }
    }
    if(i == 3)
    {
        return -1;
    }
    stime = time(NULL);
    //printf("time(NULL) = %ld\n",stime);
    ltm = localtime(&stime);
    snprintf(glob_log_system_config.log_file_path ,MAX_FILE_NAME_LEN,"%s_%d.log",FILE_NAME,ltm->tm_mday);
    printf("logfile_name = %s \n",glob_log_system_config.log_file_path);
    ltm->tm_hour = 23;
    ltm->tm_min = 59;
    ltm->tm_sec = 59;
    etime = mktime(ltm) + 1;
    //printf("mktime(ltm) = %ld\n",etime);
    its.it_value.tv_sec = etime - stime;
    its.it_value.tv_usec = 0;
    its.it_interval.tv_sec = DAY_PER_SECONDS;
    its.it_interval.tv_usec = 0;
    // its.it_interval.tv_sec = 60;
    // its.it_interval.tv_usec = 0;
    // its.it_value.tv_sec = 30;
    // its.it_value.tv_usec = 0;
    signal(SIGALRM,signal_handler);
    if(setitimer(ITIMER_REAL,&its,NULL) == -1)
    {
        printf("set timer error!\n");
        return -1;
    }
    return 0;
}

const char * level_strings[] = {"DEBUG","INFO","WARN","ERROR"};


void set_glob_log_level(LogLevel level)
{
    glob_log_system_config.level = level;
}

// 打开日志文件
static void open_log_file(FILE **log_file, const char *log_file_path) {
    *log_file = fopen(log_file_path, "a");
    if (!(*log_file)) {
        fprintf(stderr, "Error opening log file %s\n", log_file_path);
    }
}

// 关闭日志文件
static void close_log_file(FILE *log_file) {
    if (log_file) {
        fclose(log_file);
    }
}

// 获取当前时间的字符串表示
static void get_current_time_str(char *time_str) {
    time_t rawtime;
    struct tm *timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(time_str, 20, "%Y-%m-%d %H:%M:%S", timeinfo);
}

// 日志格式化函数
static void format_log_message(LogMsg *msg,const char *color,const char *format, va_list args) {
    get_current_time_str(msg->time_str);
    // 获取日志级别的字符串表示,颜色
    const char *level_str = level_strings[msg->level];
    const char *color_code =glob_log_system_config.enable_color ? color: Reset;
    char *filename1 = strrchr(msg->file, '\\');
    char *filename2 = strrchr(msg->file, '/');
    const char *filename = (filename1<filename2)?filename2:filename1;
    filename = filename ? filename+1 : msg->file;
    // 格式化日志消息
    snprintf(msg->message, MSG_SIZE, "%s[%s] [%-5s] [%s->%s:%-3d] ", color_code, msg->time_str,level_str, filename,msg->tag, msg->line);
    vsnprintf(msg->message + strlen(msg->message), MSG_SIZE - strlen(msg->message), format, args);
    strcat(msg->message, "\033[0m"); // Reset color
}

// 记录日志的核心函数
void log_message(LogLevel logger,LogLevel level, const char *tag, const char *file, int line, const char *color, const char *format,...) {
    if(level<(glob_log_system_config.level > logger? glob_log_system_config.level:logger))
        return;
    LogMsg msg = {
        .level = level,
        .tag = tag,
        .file = file,
        .line = line,
    };
    va_list args;
    va_start(args,format);
    format_log_message(&msg,color,format, args);
    va_end(args);
    // log-->终端 
    printf("%s\n", msg.message);
    // log-->文件
    if (glob_log_system_config.enable_file_logging) {
        FILE *log_file = NULL;
        open_log_file(&log_file, glob_log_system_config.log_file_path);
        if (log_file) {
            fprintf(log_file, "%s\n", msg.message);
            close_log_file(log_file);
        }
    }
}